import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.net.URL;
import java.net.MalformedURLException;

public class MineSweeperApplet extends Applet implements Runnable{

	//lets do some double buffering.
	private Image offIm=null;
	private Graphics offGraphics=null;
	private Dimension offDimension=null;

	private Image[] images;
	private Image thumbnail;
	private boolean imagesLoaded;
	private int currentImage;
	private int totalImages;

	private int width;		//The width of the applet
	private int height;		//The height of the applet


	private int progressBarExternalWidth;
	private int progressBarExternalHeight;
	private int progressBarPadding;

	private int progressBarX;
	private int progressBarY;

	private int progressStringX;
	private int progressStringY;

	private int backgroundRed;
	private int backgroundGreen;
	private int backgroundBlue;



	private MineSweeperWindow window;

	public void init()
	{


		if(!isGreaterThanJDK14())
		{
			URL upgradeTarget;
			try{
				String targetURL = getStringParam("upgradePath",
					"http://www.netsoc.tcd.ie/~duncan/dev/java/upgrade.html");
				System.out.println("Redirecting to "+targetURL+" for a later version of java");
				getAppletContext().showDocument(new URL(targetURL));

			}catch(MalformedURLException mfe)
			{
				System.err.println("Malformed URL exception caught:"+mfe);
			}

		}

		progressBarExternalWidth = getIntParam("ProgressBarExternalWidth",
												width - 30);
		progressBarExternalHeight= getIntParam("ProgressBarExternalHeight",
												height - 5);
		progressBarPadding= getIntParam("ProgressBarPadding",2);
		progressBarX= getIntParam("ProgressBarX",20);
		progressBarY= getIntParam("ProgressBarY",20);

		progressStringX= getIntParam("ProgressStringX",20);
		progressStringY= getIntParam("ProgressStringY",2);
	
		backgroundRed = getIntParam("BackgroundRed",171);
		backgroundGreen = getIntParam("BackgroundGreen",205);
		backgroundBlue = getIntParam("BackgroundBlue",239);


		imagesLoaded = false;
		System.out.println("Starting card loading thread...");		
		Thread card_loader = new Thread(this);
		card_loader.start();
	}

  
	public void paint(Graphics g) {
		update(g);
	}
  
	public void update(Graphics g) {
	
		//lets sord out double buffering
		if(offGraphics==null){
			offIm=createImage(getSize().width,getSize().height);
			offGraphics=offIm.getGraphics();
		}

		offGraphics.setColor(new Color(backgroundRed,
										backgroundGreen,
										backgroundBlue));
		offGraphics.setColor(Color.BLACK);
		offGraphics.fillRect(0,0,getSize().width,getSize().height);

		if(!imagesLoaded){
			//display a message saying we're loading the cards...
			//offGraphics.setFont(new Font("Arial",Font.PLAIN,14));
			offGraphics.setColor(Color.white);

			offGraphics.drawRect(progressBarX,progressBarY,
									progressBarExternalWidth,
									progressBarExternalHeight);

			offGraphics.drawRect(progressBarX + progressBarPadding,
									progressBarY + progressBarPadding,
									progressBarExternalWidth -
												( progressBarPadding * 2),
									progressBarExternalHeight -
												( progressBarPadding * 2));


			offGraphics.setColor(Color.BLACK);//new Color(backgroundRed,
										//backgroundGreen,
										//backgroundBlue));

			offGraphics.drawRect(progressBarX + progressBarPadding + 1,
									progressBarY + progressBarPadding + 1, 
									progressBarExternalWidth -
												( progressBarPadding * 2) - 2,
									progressBarExternalHeight -
												( progressBarPadding * 2) - 2);



			offGraphics.setColor(Color.white);
			offGraphics.fillRect(progressBarX + progressBarPadding + 1,
									progressBarY + progressBarPadding + 1, 
									(int)(((float)currentImage / 
												(float)Game.NUMBER_OF_IMAGES) * 
									(progressBarExternalWidth -
												( progressBarPadding * 2))),
									progressBarExternalHeight -
												( progressBarPadding * 2));

			offGraphics.drawString("Loading image: "+(currentImage+1)+" of "+
									(Game.NUMBER_OF_IMAGES+1),
									progressStringX,progressStringY);



		}else {
			//Images have loaded...
				  offGraphics.drawImage(thumbnail,(getSize().width/2) - 35,(getSize().height/2) - 35,this);

			
		}
		//draw buffered image.
		g.drawImage(offIm,0,0,this);
 
	}


   public void run(){

		//lets load the images here.
		
		String image_prefix = "./images/";
		String image_suffix = ".gif";

		Image images[] = new Image[Game.NUMBER_OF_IMAGES];


//		Toolkit tk = Toolkit.getDefaultToolkit();
		MineSweeperWindow msw = new MineSweeperWindow();
		MediaTracker mt = new MediaTracker(msw);
		//load the first 8 images.
		for(int i=0;i< 9; i++){


			images[i] = getImage(getCodeBase(),image_prefix + i + image_suffix);


		}
		//do the others
		images[Game.IMG_SMILEY_SMILE] = getImage(getCodeBase(),image_prefix +
										"smiley_smile" + image_suffix);
		images[Game.IMG_SMILEY_O] = getImage(getCodeBase(),image_prefix +
										"smiley_ooo" + image_suffix);
		images[Game.IMG_SMILEY_DEAD] = getImage(getCodeBase(),image_prefix +
										"smiley_dead" + image_suffix);
		images[Game.IMG_SMILEY_GLASSES] = getImage(getCodeBase(),image_prefix +
										"smiley_glasses" + image_suffix);
		images[Game.IMG_FLAG] = getImage(getCodeBase(),image_prefix + "flag" + image_suffix);
		images[Game.IMG_QUESTION_MARK] = getImage(getCodeBase(),image_prefix +
										"question_mark" + image_suffix);
		images[Game.IMG_MINE] = getImage(getCodeBase(),image_prefix + "mine" + image_suffix);     
		images[Game.IMG_LED_TOP_ON] = getImage(getCodeBase(),image_prefix + 
										"LED_top_1" + image_suffix);
		images[Game.IMG_LED_TOP_OFF] = getImage(getCodeBase(),image_prefix + 
										"LED_top_0" + image_suffix);
		images[Game.IMG_LED_LEFT_ON] = getImage(getCodeBase(),image_prefix + 
										"LED_left_1" + image_suffix);
		images[Game.IMG_LED_LEFT_OFF] = getImage(getCodeBase(),image_prefix + 
										"LED_left_0" + image_suffix);
		images[Game.IMG_LED_RIGHT_ON] = getImage(getCodeBase(),image_prefix + 
										"LED_right_1" + image_suffix);
		images[Game.IMG_LED_RIGHT_OFF] = getImage(getCodeBase(),image_prefix + 
										"LED_right_0" + image_suffix);
		images[Game.IMG_LED_MID_ON] = getImage(getCodeBase(),image_prefix + 
										"LED_mid_1" + image_suffix);
		images[Game.IMG_LED_MID_OFF] = getImage(getCodeBase(),image_prefix + 
										"LED_mid_0" + image_suffix);
		images[Game.IMG_LED_BOTTOM_ON] = getImage(getCodeBase(),image_prefix + 
										"LED_bottom_1" + image_suffix);
		images[Game.IMG_LED_BOTTOM_OFF] = getImage(getCodeBase(),image_prefix + 
										"LED_bottom_0" + image_suffix);
		images[Game.IMG_CELL_TOUCHED] = getImage(getCodeBase(),image_prefix + 
										"cell_touched" + image_suffix);
		images[Game.IMG_CELL_UNTOUCHED] = getImage(getCodeBase(),image_prefix + 
										"cell_untouched" + image_suffix);
		images[Game.IMG_ICON] = getImage(getCodeBase(),image_prefix + "icon" + image_suffix);
		images[Game.IMG_SMILEY_PRESSED] = getImage(getCodeBase(),image_prefix +
										"smiley_pressed" + image_suffix);

		

		
		for(currentImage =0;currentImage < Game.NUMBER_OF_IMAGES; currentImage ++)
		{

			mt.addImage(images[currentImage],currentImage);
			try
			{

				System.out.println("loading image "+ currentImage);
				mt.waitForID(currentImage);
				repaint();
			}catch (InterruptedException ioe)
			{
				System.out.println("Interrupted loading images..");
			}


		}
		thumbnail = getImage(getCodeBase(),getParameter("thumbnail"));
		mt.addImage(thumbnail,currentImage);
		try
		{
			mt.waitForID(currentImage);
		}
		catch (Exception e)
		{
		}

		imagesLoaded = true;
		if(this.window == null)
		{
			this.window = new MineSweeperWindow();
		
		}
		this.window.init(images);
		this.enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
		repaint();
	}

	private String getStringParam(String param,String defaultValue){

		String ans = getParameter(param);
		if(ans == null){
			ans = defaultValue;
			System.out.println("Parameter "+param+" not found. Setting to default of:"+defaultValue+".");
		}
		return ans;
	}

	private int getIntParam(String param,int defaultValue){

		String tmp_ans = getParameter(param);
		int ans;
		if(tmp_ans == null){
			ans = defaultValue;
			System.out.println("Parameter "+param+" not found. Setting to default of:"+defaultValue+".");
		}
		try
		{
			ans = Integer.parseInt(tmp_ans);
		}catch(NumberFormatException nfe)
		{
			ans = defaultValue;
			System.out.println("Error parsing parameter "+param+". Setting to default of:"+defaultValue+".");
		}

		return ans;
	}


	private boolean isGreaterThanJDK14()
	{
		/*
			(taken from http://h21007.www2.hp.com/dspp/tech/tech_TechDocumentDetailPage_IDX/1,1701,2156,00.html):

			java.class.version property values:
		
			JDK 1.1 45.3 
			JDK 1.2 46.0 
			JDK 1.3 47.0 
			JDK 1.4 48.0 

		*/
		String v = System.getProperty("java.class.version");
		String v2 = System.getProperty("java.version");
		System.out.println("java.class.version:"+v);
		System.out.println("java.version:"+v2);
		try{
			return (Double.valueOf(v).doubleValue() >= 48.0);
		}catch(NumberFormatException nfe)
		{
		}
		return false;

	}



	public void processMouseMotionEvent( MouseEvent e ){
   		if(this.window!=null && this.window.getGame() != null){
			this.window.requestFocus();
		}else {
			//this.run();
			
		}
	}


}  
  
    
      

